package com.smart.jetpackcomposestate.todo.three

import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.animateContentSize
import androidx.compose.animation.core.FastOutLinearInEasing
import androidx.compose.animation.core.FastOutSlowInEasing
import androidx.compose.animation.core.TweenSpec
import androidx.compose.animation.core.animateDpAsState
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.defaultMinSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.TextField
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.unit.dp
import com.smart.jetpackcomposestate.todo.TodoIcon
import com.smart.jetpackcomposestate.todo.TodoItem

/**
 * @author huangzehui
 * @date 2025/8/7 13:14 周四
 * @description
 */

// 排图标，根据文本框是否有内容，自动收起和弹出，带动画效果
@Composable
fun AnimatedIconRow(
    icon: TodoIcon,
    onIconChange: (todoIcon: TodoIcon) -> Unit,
    modifier: Modifier = Modifier,
    visible: Boolean = true
) {

    val enterAnim = remember {
        // 渐入动画
        fadeIn(
            // 动画间隔
            animationSpec = TweenSpec(
                // 动画执行时长，单位：ms
                durationMillis = 300,
                // 动画的执行曲线，应该是插值器，例如：先快后慢，线性动画等
                // 当前是线性动画
                easing = FastOutLinearInEasing
            )
        )
    }

    val exitAnim = remember {
        fadeOut(
            animationSpec = TweenSpec(
                durationMillis = 100,
                easing = FastOutSlowInEasing
            )
        )
    }

    Box(
        modifier = modifier
            .defaultMinSize(
                // 设置默认的最小高度
                minHeight = 16.dp
            )
    ) {
        AnimatedVisibility(
            visible = visible,
            enter = enterAnim,
            exit = exitAnim,
        ) {
            IconRow(icon = icon, onIconChange = onIconChange)
        }
    }
}

@Composable
fun IconRow(
    icon: TodoIcon,
    onIconChange: (todoIcon: TodoIcon) -> Unit,
    modifier: Modifier = Modifier
) {
    Row {
        for (todoIcon in TodoIcon.entries) {
            SelectableIconButton(
                icon = todoIcon.imageVector,
                iconContentDescription = todoIcon.contentDescription,
                onIconSelected = {
                    onIconChange(todoIcon)
                },
                isSelected = { todoIcon == icon }
            )
        }
    }
}

@Composable
fun SelectableIconButton(
    icon: ImageVector,
    iconContentDescription: Int,
    onIconSelected: () -> Unit,
    isSelected: () -> Boolean
) {
    // 图标选中和未选中状态，颜色不一样
    val tint = if (isSelected()) {
        MaterialTheme.colorScheme.primary
    } else {
        MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f)
    }

    TextButton(
        onClick = {
            onIconSelected()
        },
        shape = CircleShape
    ) {
        Column {

            Icon(
                imageVector = icon,
                tint = tint,
                contentDescription = stringResource(id = iconContentDescription)
            )

            if (isSelected()) {
                Box(
                    Modifier
                        .padding(top = 3.dp)
                        // 设置宽度为 icon 的默认宽度
                        .width(icon.defaultWidth)
                        .height(1.dp)
                        .background(color = tint),
                ) {

                }
            } else {
                Spacer(modifier = Modifier.height(4.dp))
            }
        }
    }
}


// 输入框
@Composable
fun TodoInputText(
    text: String,
    onTextChange: (String) -> Unit,
    modifier: Modifier = Modifier,
    onImeAction: () -> Unit = {},
) {
    // 键盘控制器
    val keyboardController = LocalSoftwareKeyboardController.current

    TextField(
        // 输入框显示的值
        value = text,
        // 输入框值变化回调
        onValueChange = onTextChange,

        maxLines = 1,

//        modifier = modifier.background(Color.Transparent),

        // 设置 TextField 相关颜色
        // TextFieldDefaults.textFieldColors() 改为 TextFieldDefaults.colors()
        colors = TextFieldDefaults.colors(
            // 没有焦点时候的容器颜色（背景色），设置 modifier.background(Color.Transparent) 是无效的
            unfocusedContainerColor = Color.Transparent,
            // 获取焦点时候的容器颜色（背景色）
            focusedContainerColor = Color.Transparent
        ),

        modifier = modifier,

        // 配置软键盘
        // 设置键盘 done 按钮的样式
        keyboardOptions = KeyboardOptions.Default.copy(imeAction = ImeAction.Done),
        // 设置done按钮点击事件
        keyboardActions = KeyboardActions(
            onDone = {
                onImeAction()
                // 隐藏键盘
                keyboardController?.hide()
            },
        ),


        )
}

// 按钮
@Composable
fun TodoEditButton(
    onClick: () -> Unit,
    text: String,
    modifier: Modifier = Modifier,
    enable: Boolean = false,
) {
    TextButton(
        onClick = onClick,
        // 按钮圆角
        shape = CircleShape,

        // 按钮颜色
        colors = ButtonDefaults.buttonColors(),

        modifier = modifier,
        // 是否可用
        enabled = enable
    ) {
        Text(text = text)
    }
}

/**
 * 顶部输入框加一个灰色背景
 */
@Composable
fun TodoItemInputBackground(
    modifier: Modifier = Modifier,
    elevate: Boolean,
    content: @Composable RowScope.() -> Unit,
) {
    // 阴影的动画
    val animatedElevation by animateDpAsState(
        targetValue = if (elevate) 1.dp else 0.dp, TweenSpec(
            durationMillis = 500
        ), label = ""
    )
    Surface(
        color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.05f),
        // 设置形状为矩行
        shape = RectangleShape,
        // Surface 底部有一个小小阴影
        shadowElevation = animatedElevation
    ) {
        Row(
            modifier = modifier
                // 设置内容展示动画
                .animateContentSize(animationSpec = TweenSpec(300)),
            content = content
        )
    }
}


@Composable
fun TodoItemEntryInput(onItemCompleted: (TodoItem) -> Unit) {
    // 这个函数使用remember给自己添加内存，然后在内存中存储一个由mutableStateOf 创建的MutableState<String>
    // 它是Compose的内置类型，提供了一个可观察的状态持有者。
    // val (value, setValue) = remember ( mutableStateOf (default) }
    // 对value的任何更改都将自动重新组合读取此状态的任何可组合函数。
    val (text, setText) = remember {
        // 这里面有 value属性，获取值函数（component1()），设置值函数（component2()）
        mutableStateOf("")
    }

    val (icon, setIcon) = remember {
        mutableStateOf(TodoIcon.Default)
    }

    val iconVisible = text.isNotEmpty()


    val submit = {
        onItemCompleted(TodoItem(task = text, icon))
        setText("")
        setIcon(TodoIcon.Default)
    }

    TodoItemInput(
        text = text,
        onTextChange = setText,
        icon = icon,
        onIconChange = setIcon,
        submit = submit,
        iconVisible = iconVisible,
    )
}

@Composable
fun TodoItemInput(
    text: String,
    onTextChange: (String) -> Unit,
    icon: TodoIcon,
    onIconChange: (TodoIcon) -> Unit,
    submit: () -> Unit,
    iconVisible: Boolean
) {
    Column() {
        Row(
            Modifier
                .padding(horizontal = 16.dp)
                .padding(top = 16.dp)
        ) {
            // 输入框
            TodoInputText(
                text = text,
                onTextChange = onTextChange,
                modifier = Modifier
                    .weight(1f)
                    .padding(end = 8.dp),
                onImeAction = submit
            )

            // 按钮
            TodoEditButton(
                onClick = submit,
                text = "Add",
                // 按钮在父容器垂直居中
                modifier = Modifier.align(Alignment.CenterVertically),
                enable = text.isNotEmpty()
            )
        }

        if (iconVisible) {
            AnimatedIconRow(
                icon = icon, onIconChange = onIconChange,
                modifier = Modifier.padding(top = 8.dp)
            )
        } else {
            Spacer(modifier = Modifier.height(16.dp))
        }

    }
}